home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
366_01
/
ue311c1.arc
/
EXEC.C
< prev
Wrap
C/C++ Source or Header
|
1991-10-10
|
33KB
|
1,489 lines
/* This file is for functions dealing with execution of
commands, command lines, buffers, files and startup files
written 1986 by Daniel Lawrence */
#include <stdio.h>
#include "estruct.h"
#include "eproto.h"
#include "edef.h"
#include "elang.h"
/* namedcmd: execute a named command even if it is not bound */
PASCAL NEAR namedcmd(f, n)
int f, n; /* command arguments [passed through to command executed] */
{
int (PASCAL NEAR *kfunc)(); /* ptr to the function to execute */
char buffer[NSTRING]; /* buffer to store function name */
int status;
/* if we are non-interactive.... force the command interactivly */
if (clexec == TRUE) {
/* grab token and advance past */
execstr = token(execstr, buffer, NPAT);
/* evaluate it */
strcpy(buffer, fixnull(getval(buffer)));
if (strcmp(buffer, errorm) == 0)
return(FALSE);
/* and look it up */
if ((kfunc = fncmatch(buffer)) == NULL) {
mlwrite(TEXT16);
/* "[No such Function]" */
return(FALSE);
}
/* and execute it INTERACTIVE */
clexec = FALSE;
status = (*kfunc)(f, n); /* call the function */
clexec = TRUE;
return(status);
}
/* prompt the user to type a named command */
/* and get the function name to execute */
kfunc = getname(": ");
if (kfunc == NULL) {
mlwrite(TEXT16);
/* "[No such function]" */
return(FALSE);
}
/* and then execute the command */
return((*kfunc)(f, n));
}
/* execcmd: Execute a command line command to be typed in
by the user */
PASCAL NEAR execcmd(f, n)
int f, n; /* default Flag and Numeric argument */
{
register int status; /* status return */
char cmdstr[NSTRING]; /* string holding command to execute */
/* get the line wanted */
if ((status = mlreply(": ", cmdstr, NSTRING)) != TRUE)
return(status);
execlevel = 0;
return(docmd(cmdstr));
}
/* docmd: take a passed string as a command line and translate
it to be executed as a command. This function will be
used by execute-command-line and by all source and
startup files. Lastflag/thisflag is also updated.
format of the command line is:
{# arg} <command-name> {<argument string(s)>}
*/
PASCAL NEAR docmd(cline)
char *cline; /* command line to execute */
{
register int f; /* default argument flag */
register int n; /* numeric repeat value */
int (PASCAL NEAR *fnc)();/* function to execute */
BUFFER *bp; /* buffer to execute */
int status; /* return status of function */
int oldcle; /* old contents of clexec flag */
char *oldestr; /* original exec string */
char tkn[NSTRING]; /* next token off of command line */
char bufn[NBUFN+2]; /* name of buffer to execute */
/* if we are scanning and not executing..go back here */
if (execlevel)
return(TRUE);
oldestr = execstr; /* save last ptr to string to execute */
execstr = cline; /* and set this one as current */
/* first set up the default command values */
f = FALSE;
n = 1;
lastflag = thisflag;
thisflag = 0;
if ((status = macarg(tkn)) != TRUE) { /* and grab the first token */
execstr = oldestr;
return(status);
}
/* process leadin argument */
if (gettyp(tkn) != TKCMD) {
f = TRUE;
strcpy(tkn, fixnull(getval(tkn)));
n = asc_int(tkn);
/* and now get the command to execute */
if ((status = macarg(tkn)) != TRUE) {
execstr = oldestr;
return(status);
}
}
/* and match the token to see if it exists */
if ((fnc = fncmatch(tkn)) == NULL) {
/* construct the buffer name */
strcpy(bufn, "[");
strcat(bufn, tkn);
strcat(bufn, "]");
/* find the pointer to that buffer */
if ((bp=bfind(bufn, FALSE, 0)) == NULL) {
mlwrite(TEXT16);
/* "[No such Function]" */
execstr = oldestr;
return(FALSE);
}
/* execute the buffer */
oldcle = clexec; /* save old clexec flag */
clexec = TRUE; /* in cline execution */
while (n-- > 0)
if ((status = dobuf(bp)) != TRUE)
break;
cmdstatus = status; /* save the status */
clexec = oldcle; /* restore clexec flag */
execstr = oldestr;
return(status);
}
/* save the arguments and go execute the command */
oldcle = clexec; /* save old clexec flag */
clexec = TRUE; /* in cline execution */
status = (*fnc)(f, n); /* call the function */
cmdstatus = status; /* save the status */
clexec = oldcle; /* restore clexec flag */
execstr = oldestr;
return(status);
}
/* token: chop a token off a string
return a pointer past the token
*/
char *PASCAL NEAR token(src, tok, size)
char *src, *tok; /* source string, destination token string */
int size; /* maximum size of token */
{
register int quotef; /* is the current string quoted? */
register char c; /* temporary character */
/* first scan past any whitespace in the source string */
while (*src == ' ' || *src == '\t')
++src;
/* scan through the source string */
quotef = FALSE;
while (*src) {
/* process special characters */
if (*src == '~') {
++src;
if (*src == 0)
break;
switch (*src++) {
case 'r': c = 13; break;
case 'n': c = 13; break;
case 'l': c = 10; break;
case 't': c = 9; break;
case 'b': c = 8; break;
case 'f': c = 12; break;
default: c = *(src-1);
}
if (--size > 0) {
*tok++ = c;
}
} else {
/* check for the end of the token */
if (quotef) {
if (*src == '"')
break;
} else {
if (*src == ' ' || *src == '\t')
break;
}
/* set quote mode if quote found */
if (*src == '"')
quotef = TRUE;
/* record the character */
c = *src++;
if (--size > 0)
*tok++ = c;
}
}
/* terminate the token and exit */
if (*src)
++src;
*tok = 0;
return(src);
}
PASCAL NEAR macarg(tok) /* get a macro line argument */
char *tok; /* buffer to place argument */
{
int savcle; /* buffer to store original clexec */
int status;
savcle = clexec; /* save execution mode */
clexec = TRUE; /* get the argument */
status = nextarg("", tok, NSTRING, ctoec('\r'));
clexec = savcle; /* restore execution mode */
return(status);
}
/* nextarg: get the next argument */
PASCAL NEAR nextarg(prompt, buffer, size, terminator)
char *prompt; /* prompt to use if we must be interactive */
char *buffer; /* buffer to put token into */
int size; /* size of the buffer */
int terminator; /* terminating char to be used on interactive fetch */
{
register char *sp; /* return pointer from getval() */
/* if we are interactive, go get it! */
if (clexec == FALSE)
return(getstring(prompt, buffer, size, terminator));
/* grab token and advance past */
execstr = token(execstr, buffer, size);
/* evaluate it */
if ((sp = getval(buffer)) == NULL)
return(FALSE);
strcpy(buffer, sp);
return(TRUE);
}
/* storemac: Set up a macro buffer and flag to store all
executed command lines there */
PASCAL NEAR storemac(f, n)
int f; /* default flag */
int n; /* macro number to use */
{
register struct BUFFER *bp; /* pointer to macro buffer */
char bname[NBUFN]; /* name of buffer to use */
/* must have a numeric argument to this function */
if (f == FALSE) {
mlwrite(TEXT111);
/* "No macro specified" */
return(FALSE);
}
/* range check the macro number */
if (n < 1 || n > 40) {
mlwrite(TEXT112);
/* "Macro number out of range" */
return(FALSE);
}
/* construct the macro buffer name */
strcpy(bname, "[Macro xx]");
bname[7] = '0' + (n / 10);
bname[8] = '0' + (n % 10);
/* set up the new macro buffer */
if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) {
mlwrite(TEXT113);
/* "Can not create macro" */
return(FALSE);
}
/* and make sure it is empty */
bclear(bp);
/* and set the macro store pointers to it */
mstore = TRUE;
bstore = bp;
return(TRUE);
}
/* storeproc: Set up a procedure buffer and flag to store all
executed command lines there */